<?php
    // +----------------------------------------------------------------------
    // | 海豚PHP框架 [ DolphinPHP ]
    // +----------------------------------------------------------------------
    // | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
    // +----------------------------------------------------------------------
    // | 官方网站: http://dolphinphp.com
    // +----------------------------------------------------------------------
    // | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
    // +----------------------------------------------------------------------

    namespace app\admin\controller;

    use app\common\controller\Common;
    use app\common\builder\ZBuilder;
    use app\admin\model\Menu as MenuModel;
    use app\admin\model\Module as ModuleModel;
    use app\admin\model\Icon as IconModel;
    use app\user\model\Role as RoleModel;
    use app\user\model\Message as MessageModel;
    use app\user\model\User;
    use think\facade\Cache;
    use think\Db;
    use think\facade\Env;
    use think\Loader;
    use think\helper\Hash;

    /**
     * 后台公共控制器
     *
     * @package app\admin\controller
     */
    class Admin extends Common
    {
        /**
         * 初始化
         *
         * @author 蔡伟明 <314013107@qq.com>
         */
        protected function initialize()
        {

            parent::initialize();
            // 是否拒绝ie浏览器访问
            if (config('system.deny_ie') && get_browser_type() == 'ie')
            {
                $this->redirect('admin/ie/index');
            }

            // 判断是否登录，并定义用户ID常量

            if (!Env::get('UID'))
            {
                Env::set('UID',$this->isLogin());
            }


            // 设置当前角色菜单节点权限
            role_auth();

            // 检查权限
            if (!RoleModel::checkAuth())
                $this->error('权限不足！');

            // 设置分页参数
            $this->setPageParam();

            // 如果不是ajax请求，则读取菜单
            if (!$this->request->isAjax())
            {
                // 读取顶部菜单
                $this->assign('_top_menus',MenuModel::getTopMenu(config('top_menu_max'),'_top_menus'));

                // 读取全部顶级菜单
                $this->assign('_top_menus_all',MenuModel::getTopMenu('','_top_menus_all'));

                // 获取侧边栏菜单
                $this->assign('_sidebar_menus',MenuModel::getSidebarMenu());
                // 获取面包屑导航
                $this->assign('_location',MenuModel::getLocation('',true));
                // 获取当前用户未读消息数量
                $this->assign('_message',MessageModel::getMessageCount());
                // 获取自定义图标
                $this->assign('_icons',IconModel::getUrls());
                // 构建侧栏
                $data        = [
                    'table'      => 'admin_config', // 表名或模型名
                    'prefix'     => 1,
                    'module'     => 'admin',
                    'controller' => 'system',
                    'action'     => 'quickedit',
                ];
                $table_token = substr(sha1('_aside'),0,8);
                session($table_token,$data);
                $settings = [
                    [
                        'title'   => '站点开关',
                        'tips'    => '站点关闭后将不能访问',
                        'checked' => Db::name('admin_config')->where('id',1)->value('value'),
                        'table'   => $table_token,
                        'id'      => 1,
                        'field'   => 'value'
                    ]
                ];

                ZBuilder::make('aside')->addBlock('switch','系统设置',$settings);


            }
        }



        /**
         * 获取当前操作模型
         *
         * @author 蔡伟明 <314013107@qq.com>
         * @return object|\think\db\Query
         */
        final protected function getCurrModel()
        {

            $table_token = input('param._t','');
            $module      = $this->request->module();
            $controller  = parse_name($this->request->controller());

            $table_token == '' && $this->error('缺少参数');
            !session('?' . $table_token) && $this->error('参数错误');

            $table_data = session($table_token);
            $table      = $table_data['table'];

            $Model = null;
            if ($table_data['prefix'] == 2)
            {
                // 使用模型
                try
                {
                    $Model = Loader::model($table);
                }
                catch (\Exception $e)
                {
                    $this->error('找不到模型：' . $table);
                }
            }
            else
            {
                // 使用DB类
                $table == '' && $this->error('缺少表名');
                if ($table_data['module'] != $module || $table_data['controller'] != $controller)
                {
                    $this->error('非法操作');
                }

                $Model = $table_data['prefix'] == 0 ? Db::table($table) : Db::name($table);
            }

            return $Model;
        }

        /**
         * 设置分页参数
         *
         * @author 蔡伟明 <314013107@qq.com>
         */
        final protected function setPageParam()
        {

            _system_check();
            $list_rows = input('?param.list_rows') ? input('param.list_rows') : config('list_rows');
            config('paginate.list_rows',$list_rows);
            config('paginate.query',input('get.'));
        }

        /**
         * 检查是否登录，没有登录则跳转到登录页面
         *
         * @author 蔡伟明 <314013107@qq.com>
         * @return int
         */
        final protected function isLogin()
        {

            // 判断是否登录
            if ($uid = is_signin())
            {
                // 已登录
                return $uid;
            }
            else
            {
                // 未登录
                $this->redirect('user/publics/signin');
            }
        }

        /**
         * 禁用
         *
         * @param array $record 行为日志内容
         *
         * @author 蔡伟明 <314013107@qq.com>
         * @return mixed
         */
        public function disable($record = [])
        {

            return $this->setStatus('disable',$record);
        }

        /**
         * 启用
         *
         * @param array $record 行为日志内容
         *
         * @author 蔡伟明 <314013107@qq.com>
         * @return mixed
         */
        public function enable($record = [])
        {

            return $this->setStatus('enable',$record);
        }

        /**
         * 启用
         *
         * @param array $record 行为日志内容
         *
         * @author 蔡伟明 <314013107@qq.com>
         * @return mixed
         */
        public function delete($record = [])
        {

            return $this->setStatus('delete',$record);
        }

        /**
         * 快速编辑
         *
         * @param array $record 行为日志内容
         *
         * @author 蔡伟明 <314013107@qq.com>
         */
        public function quickEdit($record = [])
        {

            $field           = input('post.name','');
            $value           = input('post.value','');
            $type            = input('post.type','');
            $id              = input('post.pk','');
            $validate        = input('post.validate','');
            $validate_fields = input('post.validate_fields','');

            $field == '' && $this->error('缺少字段名');
            $id == '' && $this->error('缺少主键值');

            $Model         = $this->getCurrModel();
            $protect_table = [
                '__ADMIN_USER__',
                '__ADMIN_ROLE__',
                config('database.prefix') . 'admin_user',
                config('database.prefix') . 'admin_role',
            ];

            // 验证是否操作管理员
            if (in_array($Model->getTable(),$protect_table) && $id == 1)
            {
                $this->error('禁止操作超级管理员');
            }

            // 验证器
            if ($validate != '')
            {
                $validate_fields = array_flip(explode(',',$validate_fields));
                if (isset($validate_fields[$field]))
                {
                    $result = $this->validate([$field => $value],$validate . '.' . $field);
                    if (true !== $result)
                        $this->error($result);
                }
            }

            switch($type)
            {
                // 日期时间需要转为时间戳
                case 'combodate':
                    $value = strtotime($value);
                    break;
                // 开关
                case 'switch':
                    $value = $value == 'true' ? 1 : 0;
                    break;
                // 开关
                case 'password':
                    $value = Hash::make((string)$value);
                    break;
            }

            // 主键名
            $pk     = $Model->getPk();
            $result = $Model->where($pk,$id)->setField($field,$value);

            cache('hook_plugins',null);
            cache('system_config',null);
            cache('access_menus',null);
            if (false !== $result)
            {
                // 记录行为日志
                if (!empty($record))
                {
                    call_user_func_array('action_log',$record);
                }
                $this->success('操作成功');
            }
            else
            {
                $this->error('操作失败');
            }
        }

        /**
         * 自动创建添加页面
         *
         * @author caiweiming <314013107@qq.com>
         */
        public function add()
        {

            // 获取表单项
            $cache_name = $this->request->module() . '/' . parse_name($this->request->controller()) . '/add';
            $cache_name = strtolower($cache_name);
            $form       = Cache::get($cache_name,[]);
            if (!$form)
            {
                $this->error('自动新增数据不存在，请重新打开此页面');
            }

            // 保存数据
            if ($this->request->isPost())
            {
                // 表单数据
                $data = $this->request->post();
                $_pop = $this->request->get('_pop');

                // 验证
                if ($form['validate'] != '')
                {
                    $result = $this->validate($data,$form['validate']);
                    if (true !== $result)
                        $this->error($result);
                }

                // 是否需要自动插入时间
                if ($form['auto_time'] != '')
                {
                    $now_time = $this->request->time();
                    foreach ($form['auto_time'] as $item)
                    {
                        if (strpos($item,'|'))
                        {
                            list($item,$format) = explode('|',$item);
                            $data[$item] = date($format,$now_time);
                        }
                        else
                        {
                            $data[$item] = $form['format'] != '' ? date($form['format'],$now_time) : $now_time;
                        }
                    }
                }

                // 插入数据
                if (Db::name($form['table'])->insert($data))
                {
                    if ($_pop == 1)
                    {
                        $this->success('新增成功',null,'_parent_reload');
                    }
                    else
                    {
                        $this->success('新增成功',$form['go_back']);
                    }
                }
                else
                {
                    $this->error('新增失败');
                }
            }

            // 显示添加页面
            return ZBuilder::make('form')->addFormItems($form['items'])->fetch();
        }

        /**
         * 自动创建编辑页面
         *
         * @param string $id 主键值
         *
         * @author caiweiming <314013107@qq.com>
         */
        public function edit($id = '')
        {

            if ($id === '')
                $this->error('参数错误');

            // 获取表单项
            $cache_name = $this->request->module() . '/' . parse_name($this->request->controller()) . '/edit';
            $cache_name = strtolower($cache_name);
            $form       = Cache::get($cache_name,[]);
            if (!$form)
            {
                $this->error('自动编辑数据不存在，请重新打开此页面');
            }

            // 保存数据
            if ($this->request->isPost())
            {
                // 表单数据
                $data = $this->request->post();
                $_pop = $this->request->get('_pop');

                // 验证
                if ($form['validate'] != '')
                {
                    $result = $this->validate($data,$form['validate']);
                    if (true !== $result)
                        $this->error($result);
                }

                // 是否需要自动插入时间
                if ($form['auto_time'] != '')
                {
                    $now_time = $this->request->time();
                    foreach ($form['auto_time'] as $item)
                    {
                        if (strpos($item,'|'))
                        {
                            list($item,$format) = explode('|',$item);
                            $data[$item] = date($format,$now_time);
                        }
                        else
                        {
                            $data[$item] = $form['format'] != '' ? date($form['format'],$now_time) : $now_time;
                        }
                    }
                }

                // 更新数据
                if (false !== Db::name($form['table'])->update($data))
                {
                    if ($_pop == 1)
                    {
                        $this->success('编辑成功',null,'_parent_reload');
                    }
                    else
                    {
                        $this->success('编辑成功',$form['go_back']);
                    }
                }
                else
                {
                    $this->error('编辑失败');
                }
            }

            // 获取数据
            $info = Db::name($form['table'])->find($id);

            // 使用ZBuilder快速创建表单
            return ZBuilder::make('form')->setPageTitle('编辑')->addFormItems($form['items'])->setFormData($info)->fetch();
        }

        /**
         * 设置状态
         * 禁用、启用、删除都是调用这个内部方法
         *
         * @param string $type   操作类型：enable,disable,delete
         * @param array  $record 行为日志内容
         *
         * @author 蔡伟明 <314013107@qq.com>
         * @return mixed
         */
        public function setStatus($type = '',$record = [],$Model = null)
        {

            $ids   = $this->request->isPost() ? input('post.ids/a') : input('param.ids');
            $ids   = (array)$ids;
            $field = input('param.field','status');

            empty($ids) && $this->error('缺少主键');
            if ($Model === null)
            {
                $Model = $this->getCurrModel();
            }

            $protect_table = [
                '__ADMIN_USER__',
                '__ADMIN_ROLE__',
                '__ADMIN_MODULE__',
                config('database.prefix') . 'admin_user',
                config('database.prefix') . 'admin_role',
                config('database.prefix') . 'admin_module',
            ];

            // 禁止操作核心表的主要数据
            if (in_array($Model->getTable(),$protect_table) && in_array('1',$ids))
            {
                $this->error('禁止操作');
            }

            // 主键名称
            $pk     = $Model->getPk();
            $map[]  = [$pk,'in',$ids];
            $result = false;
            $module = Db::name('admin_module')->where(['system_module' => 0])->whereNotIn('name','apps')->column('id,name');
            if (in_array($this->request->module(),$module))
            {
                $Model->where(['app_id' => \env('app_id')]);
            }
            switch($type)
            {
                case 'disable': // 禁用
                    $result = $Model->where($map)->setField($field,0);
                    break;
                case 'enable': // 启用
                    $result = $Model->where($map)->setField($field,1);
                    break;
                case 'delete': // 删除
                    $result = $Model->where($map)->delete();
                    break;
                default:
                    $this->error('非法操作');
                    break;
            }

            if (false !== $result)
            {
                Cache::clear();
                // 记录行为日志
                if (!empty($record))
                {
                    call_user_func_array('action_log',$record);
                }
                $this->success('操作成功');
            }
            else
            {
                $this->error('操作失败');
            }
        }

        /**
         * 模块设置
         *
         * @author 蔡伟明 <314013107@qq.com>
         * @return mixed
         */
        public function moduleConfig()
        {

            // 当前模块名
            $module = $this->request->module();

            // 保存
            if ($this->request->isPost())
            {
                $data = $this->request->post();
                $data = json_encode($data);

                if (false !== ModuleModel::where('name',$module)->update(['config' => $data]))
                {
                    cache('module_config_' . $module,null);
                    $this->success('更新成功');
                }
                else
                {
                    $this->error('更新失败');
                }
            }

            // 模块配置信息
            $module_info = ModuleModel::getInfoFromFile($module);
            $config      = $module_info['config'];
            $trigger     = isset($module_info['trigger']) ? $module_info['trigger'] : [];

            // 数据库内的模块信息
            $db_config = ModuleModel::where('name',$module)->value('config');
            $db_config = json_decode($db_config,true);

            // 使用ZBuilder快速创建表单
            return ZBuilder::make('form')->setPageTitle('模块设置')->addFormItems($config)->setFormdata($db_config)// 设置表格数据
            ->setTrigger($trigger)// 设置触发
            ->fetch();
        }
    }
